package com.javasm.adminapi.login.service.impl;

import com.javasm.adminapi.common.Parameter;
import com.javasm.adminapi.common.exception.ExceptionEnum;
import com.javasm.adminapi.common.exception.JavasmException;
import com.javasm.adminapi.login.model.LoginUser;
import com.javasm.adminapi.login.service.LoginService;

import com.javasm.adminapi.module.system.dto.MenuTypeDTO;
import com.javasm.adminapi.module.system.entity.User;
import com.javasm.adminapi.module.system.service.PermissionService;
import com.javasm.adminapi.module.system.service.UserService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.List;

/**
 * @className: LoginServiceImpl
 * @description:
 * @author: zcx
 * @date: 2025/10/15 10:32
 * @version: 0.1
 * @since: jdk17
 */
@Service
@Log4j2
public class LoginServiceImpl implements LoginService {

    @Resource
    HttpSession session;

    @Autowired
    UserService userService;
    @Resource
    PasswordEncoder passwordEncoder;

    @Resource
    private PermissionService permissionService;
    @Override
    public User login(User loginUser) {
        //验证code
        String username = loginUser.getUsername();
        String password = loginUser.getPassword();
        String code = loginUser.getCode();
        Object jsonCode = session.getAttribute("json_code");
        String jsonCodeStr = jsonCode==null?"": jsonCode.toString();
        if(code==null||code.isEmpty()||!code.equals(jsonCodeStr)){
            throw new JavasmException(ExceptionEnum.Code_Error);
        }
        User user = userService.getByUsername(username);
        if (user == null){
            throw new JavasmException(ExceptionEnum.User_Not_Found);
        }
        if(!passwordEncoder.matches(password,user.getPassword())){
            throw new JavasmException(ExceptionEnum.UserNamePassword_Error);
        }

        List<MenuTypeDTO> urlList = permissionService.getMenuType(user.getId());
        user.setUrlList(urlList);
        user.setLastLoginTime(new Date());
        userService.updateById(user);
        UserDetails userDetails = new LoginUser(user);
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new
                UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
        return user;
    }

    @Override
    public User getLoginUser() {
        SecurityContext context = SecurityContextHolder.getContext();
        if (context == null){
            return null;
        }
        Authentication authentication = context.getAuthentication();
        if (authentication == null){
            return null;
        }
        Object principal = authentication.getPrincipal();
        if (principal == null){
            return null;
        }
        System.out.println(principal.getClass());
        LoginUser loginUser = (LoginUser) principal;
        return loginUser.getUser();
    }


    @Override
    public void uploadInfo(User user) {
        User loginUser = getLoginUser();
        if(loginUser == null){
            throw new JavasmException(ExceptionEnum.Not_Login);
        }
        user.setId(loginUser.getId());
        if(user.getPassword()!=null&&!user.getPassword().isEmpty()){
            String password = passwordEncoder.encode(user.getPassword());
            user.setPassword(password);
        }
        userService.updateById(user);
    }
}
